package com.jsg.sl651.message.handler;

import com.jsg.sl651.annotations.FunctionHandler;
import com.jsg.sl651.entity.frame.FrameMessageWrapper;
import com.jsg.sl651.entity.frame.body.returns.ReturnMessageBody;
import com.jsg.sl651.util.ByteUtil;
import com.jsg.sl651.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Handler 处理中心
 */
@Slf4j
public final class HandlerFactory {

    private static final Map<Integer, List<Handler>> HANDLER_MAP = new ConcurrentHashMap<>();
    private static final List<Handler> DEFAULT_HANDLER = new ArrayList<Handler>(){{add(new DefaultHandler());}};


    private static List<Handler> getHandler(int functionCode) {
        List<Handler> handlers = HANDLER_MAP.get(functionCode);
        if (handlers == null || handlers.isEmpty()) {
            return DEFAULT_HANDLER ;
        }
        return handlers;
    }


    public static ReturnMessageBody handle(FrameMessageWrapper frameMessageWrapper) {
        List<Handler> handlers = getHandler(frameMessageWrapper.getHeader().getFunction().getCode());
        ReturnMessageBody returnMessage = null;
        for (Handler handler : handlers) {
            returnMessage = handler.handle(frameMessageWrapper);
        }
        return returnMessage;
    }



    private static void init() {
        // 注册已有的handler
        Map<String, Handler> beansOfType = SpringUtil.getBeansOfType(Handler.class);
        for (Handler handler : beansOfType.values()) {
            register(handler);
        }
    }


    public static void register(List<Handler> handlers) {
        if (handlers == null) {
            return;
        }
        for (Handler handler : handlers) {
            register(handler);
        }
    }


    public static void register(Handler handler) {
        if (handler == null) {
            return;
        }
        FunctionHandler annotation = handler.getClass().getAnnotation(FunctionHandler.class);
        if (annotation == null) {
            throw new RuntimeException("HandlerFactory 注册失败：" + handler.getClass().getName() + " 没有 @FunctionHandler 注解");
        } else {
            int i = annotation.functionCode();
            List<Handler> handlers = HANDLER_MAP.get(i);
            if (handlers == null) {
                handlers = new ArrayList<>();
            }
            handlers.add(handler);
            HANDLER_MAP.put(i, handlers);
            log.info("HandlerFactory 注册成功：" + handler.getClass().getName() + " 方法码：" + ByteUtil.toHex((byte) i));
        }
    }


}
